feat(scanner): index projects rooted at a symlink#258
Open
kryptt wants to merge 1 commit into
Open
Conversation
filepath.WalkDir does not descend into symlinked directories, so a project rooted at a symlink would silently enumerate zero files — hostile to common patterns like ~/.emacs.d/emacs-sources -> /usr/share/emacs/30.2/ where a stable name fronts a versioned path so the workspace survives upstream version bumps. NewScanner now Lstats the root and, only if it is a symlink, resolves it once via filepath.EvalSymlinks before WalkDir runs. Intermediate symlinks deeper in the tree are still ignored, matching upstream's prior caution against recursion loops. We deliberately do NOT call EvalSymlinks on a real directory: doing so would rewrite parent-directory symlinks (e.g. /usr/local on a Nix system) and shift the project's stored path in ways the caller never asked for. Two tests cover both cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
`filepath.WalkDir` does not descend into symlinked directories, so when a user points grepai at a project root that is itself a symlink, the scan silently enumerates zero files. There's no warning — just no results.
This is hostile to a common pattern: fronting a version-managed path with a stable name so the workspace survives upstream version bumps. For example:
```
~/.emacs.d/emacs-sources -> /usr/share/emacs/30.2/
```
A user puts `emacs-sources` in their workspace config so they don't have to retarget on every emacs upgrade. Today, that workspace indexes nothing.
Solution
`NewScanner` now `os.Lstat`s the root and, only if it is a symlink to a directory, resolves it once via `filepath.EvalSymlinks` before `WalkDir` runs. Intermediate symlinks deeper in the tree are still skipped — that matches upstream's existing behavior and avoids recursion loops or surprising blow-ups when packages vendor third-party trees via symlinks.
We deliberately do not call `EvalSymlinks` on a real directory: doing so would also rewrite parent-directory symlinks (e.g. `/usr/local` on a Nix system) and silently shift the project's stored path in ways the caller never asked for. The `os.Lstat` guard makes the resolution opt-in based on the root entry's own type.
Test plan
Two new tests in `indexer/scanner_test.go`:
Both tests `t.Skipf` cleanly on environments that cannot create symlinks. All existing tests continue to pass (`go test ./...`).